<template>
  <div class="switchbox-map-content">
    <div id="switchbox-map">
      <map-toolbar
        :webmoduleId="62"
        :filter-options="{
          flat: true,
          excludeCommands: ['switchboxportlink', 'setellipse', 'setcircle', 'setlink', 'choseData', 'choseData2', 'beforeView', 'afterView']
        }"
        @command="handleToolbarCommand"
      />
    </div>
    <div
      v-dialog-drag="{
        restrict: true,
        initPosition: false,
        parent: '.switchbox-map-content'
      }"
      class="floating-panel"
      v-show="showFloatingPanel"
    >
      <div class="panel-header dialog-header">
        {{ panelTitle }}
        <i class="el-icon-close close-btn" @click.stop="closePanel"></i>
      </div>
      <div class="custom-list">
        <div class="list-header">
          <div class="header-item">型号</div>
          <div class="header-item">生产厂家</div>
        </div>
        <div class="list-body">
          <div class="list-row" v-for="(item, index) in panelData" :key="index" @click.stop="getSwitchBoxTemplate(item)">
            <div class="row-item">{{ item.model }}</div>
            <div class="row-item">{{ item.factory }}</div>
          </div>
        </div>
      </div>
    </div>
    <!-- 新增树形弹框 -->
    <div
      v-dialog-drag="{
        restrict: true,
        initPosition: false,
        parent: '.switchbox-map-content'
      }"
      class="floating-panel tree-dialog"
      v-if="treeDialogVisible"
    >
      <div class="panel-header dialog-header">
        光纤连接
        <i class="el-icon-close close-btn" @click.stop="treeDialogVisible = false"></i>
      </div>
      <div class="tree-container">
        <el-tree ref="tree" :data="processedTreeData" node-key="id" :props="treeProps" :default-expanded-keys="expandedKeys" @node-mouseenter="handleNodeMouseEnter" @node-mouseleave="handleNodeMouseLeave">
          <span class="custom-tree-node" slot-scope="{ node, data }" @mouseenter="handleNodeMouseEnter(node)" @mouseleave="handleNodeMouseLeave">
            <!-- <el-checkbox v-model="data.checked" v-if="data.selectParent" @change="handleCustomCheckChange(node, data)" @click.native.stop="" /> -->
            <img v-if="data.type === '3'" :src="data.iconsrc" alt="">
            <span>{{ node.label }}</span>
            <div class="node-actions" v-if="data.type === '2'" v-show="hoverNodeId === node.id">
              <el-button v-if="data.type === '2'" @click.stop="batchConnect(node)" type="text">批量连接</el-button>
              <el-button v-if="data.type === '2'" @click.stop="batchDelete(node)" type="text">批量删除</el-button>
            </div>
            <div class="node-actions" v-if="data.type === '3'" v-show="hoverNodeId === node.id">
              <el-button v-if="!data.weldTwo" @click.stop="connect(node)" type="text">连接</el-button>
              <el-button v-if="data.weldTwo" @click.stop="deleteConnect(node)" type="text">删除连接</el-button>
            </div>
          </span>
        </el-tree>
      </div>
    </div>
  </div>
</template>

<script>
import L from '@/libs/leaflet'
import SuperMap from '@/libs/supermap'
import { get, find, each } from 'lodash'
import MapToolbar from '../home/components/mapTools.vue'
import { getSysMapInfoApi, getLayerManagerInfoApi } from '@/deps/api'
import { sessionStorage } from '@/deps/utils'
import { mapService, mapObj, createLayerManager, highlightStyle, featureService, checkGuideLines, spColorToGeneral } from '@/widgets/mapUtils'
import { getParaInfoApi, insertSwitchBoxEquipmentApi, getCableTreeByOptlineidsApi, saveSwitchbox_PortLineApi, saveRcabTportApi } from '@/deps/apis/switchApi'
let featuresDatas = []
let sysMapInfo = null
let switchboxMapObj = null
let rootid_equip = null
let messageInstance = null
let nowFeatureData = null
let frameLayers = []
let connections = []  // 存储所有连线
let drawingPoints = []
let tempLine = null
let notifyInstance = null
const imgNoWeld = require('../../static/images/NoWeld.png')
const imgWeldOne = require('../../static/images/WeldOne.png')
const imgWeldTwo = require('../../static/images/WeldTwo.png')
export default {
  name: 'SwitchBox',
  components: {
    MapToolbar
  },
  computed: {
    processedTreeData() {
      return this.processNodeData(this.treeData)
    }
  },
  data() {
    return {
      isDrawing: false, // 新增的绘制状态变量
      highlightLayer: null,
      featureData: null,
      crsConfig: null,
      layerManager: null,
      boxsData: [{ factory: '', equipment: '屏幕墙3*2', id: '11600' }, { equipment: '小区144芯14配纤盘光交配线架' }],
      linesData: [{ equipment: '小区288芯26配纤盘光交配线架' }, { equipment: '小区144光交配线架' }, { factory: '无锡宏达', equipment: '分纤箱机架', id: '13057' }],
      showFloatingPanel: false,
      panelData: [],
      panelTitle: '',
      treeDialogVisible: false,
      hoverNodeId: null,
      treeData: [],
      expandedKeys: [],
      treeProps: {
        label: 'name',
        children: 'children',
        disabled: data => data.type === '1' && !data.selectParent // 修改为直接使用布尔值
      },
      isMoving: false,
      selectedConnection: null,  // 移回到 data 中
      guideLines: [] // 用于存储辅助线的数组
    }
  },
  async created() {
    const featureData = sessionStorage('switchbox_feature')
    if (featureData) this.featureData = featureData
    window.addEventListener('beforeunload', this.handleBeforeUnload)
    this.boxsData = await getParaInfoApi({ tablename: 'VIEW_RPARA_CHASSIS' })
    this.linesData = await getParaInfoApi({ tablename: 'VIEW_RPARA_OLightBranchDevice' })
  },
  async mounted() {
    console.error(L)
    sysMapInfo = await getSysMapInfoApi({ webmoduleId: 62, rootClassType: 2 })
    try {
      const mapInfo = await new Promise((resolve, reject) => {
        mapService.getMapInfo(serviceResult => {
          if (serviceResult.error) reject(serviceResult.error)
          else {
            resolve(serviceResult.result)
            this.initMap(mapInfo)
          }
        })
      })
      switchboxMapObj.on('zoomend', this.afterMoveend)
      switchboxMapObj.on('pm:drawstart', ({ workingLayer }) => {
        console.error('开始绘制', workingLayer) // 调试用，确保方法被调用
        this.isDrawing = true
      })
      switchboxMapObj.on('pm:create', ({layer}) => {
        console.log(layer.toGeoJSON());
      })
      switchboxMapObj.on('pm:drawend', (data) => {
        console.error('结束绘制', data) // 调试用，确保方法被调用
        this.isDrawing = false
      })
    } catch (error) {
      console.error('获取地图服务信息失败:', error)
    }
  },
  methods: {
    afterMoveend() {
      console.log('地图移动结束')
      this.layerManager && this.layerManager.clearLayers()
      this.layerOnMapByFeatures()
    },
    clearNowHighlightLayer(nowMap = switchboxMapObj) {
      console.error('清除高亮') // 调试用，确保方法被调用
      // 清除之前的高亮
      if (this.highlightLayer) {
        nowMap.removeLayer(this.highlightLayer)
        nowFeatureData = null
      }
    },
    highlightLayerAction(feature, nowMap = switchboxMapObj) {
      this.clearNowHighlightLayer(nowMap)
      // 创建高亮图层并置顶
      this.highlightLayer = L.geoJSON(feature, {
        style: highlightStyle
      })
      this.highlightLayer.addTo(nowMap)
      this.highlightLayer.bringToFront()  // 确保图层置顶
      this.highlightLayer.on('click', (e) => {
        L.DomEvent.stopPropagation(e); // 阻止事件冒泡
        L.DomEvent.preventDefault(e); // 阻止默认行为
        if (this.treeDialogVisible) {
          return;
        }
        this.clearNowHighlightLayer(nowMap)
      })
    },
    handleBeforeUnload(e) {
      const confirmationMessage = '刷新页面将返回网络资源页面'
      e.returnValue = confirmationMessage
      return confirmationMessage
    },
    async initMap(mapInfo) {
      if (switchboxMapObj) switchboxMapObj.remove()
      const bounds = L.bounds(L.point(0, 0), L.point(12000, 12000))
      this.crsConfig = L.CRS.NonEarthCRS({ bounds, origin: L.point(0, 12000) })
      switchboxMapObj = L.map('switchbox-map', {
        crs: this.crsConfig,
        center: [12000, 10000],
        zoom: 6,
        zoomControl: false,
        attributionControl: false,
        detectRetina: true,
        maxZoom: 20,
        minZoom: 0
      })
      this.getLayering = true
      await this.layerOnMapByFeatures(true)
    },
    async layerOnMapByFeatures(isFirstLoad = false) {
      try {
        if (!featuresDatas || featuresDatas.length === 0) {
          const res = await getLayerManagerInfoApi({ menuid: '680', rootClassType: 3 })
          if (res && Array.isArray(res)) {
            featuresDatas = res.reduce((acc, item) => {
              if (item.child && Array.isArray(item.child)) acc.push(...item.child)
              return acc
            }, [])
          }
        }
        if (!this.layerManager) this.layerManager = createLayerManager(switchboxMapObj)
        await this.layerManager.loadMaps(featuresDatas, this.featureData)
        // 计算所有图层的边界并居中显示
        const layers = this.layerManager.dataFeatureGroup.getLayers()
        if (layers.length > 0) {
          const bounds = L.latLngBounds([])
          // 定义局部变量存储连接关系
          let fiberConnections = [];
          layers.forEach(layer => {
            if (layer && layer.getBounds) {
              bounds.extend(layer.getBounds())
            }
            const properties = get(layer, 'feature.properties', {})
            // 其他图层的点击事件处理
            layer.on('click', (e) => {
              if (this.isMoving) return; // 如果正在移动，不处理点击事件
              L.DomEvent.stopPropagation(e); // 阻止事件冒泡
              L.DomEvent.preventDefault(e); // 阻止默认行为
              if (this.isDrawing) return; // 如果正在绘制，不处理点击事件
              const {FEATURENAME} = get(e.target, 'feature.properties', {});
              console.error(FEATURENAME, 'FEATURENAME')
              if (FEATURENAME === '端口') {
                console.error(nowFeatureData)
                if (!this.isDrawingLine) {
                  this.highlightLayerAction(e.target.feature)
                  // 如果不在连线状态，不处理
                  nowFeatureData = e.target.feature;
                  return
                }
                nowFeatureData = e.target.feature;
                const fiberId = get(layer, 'feature.properties.SMID');
                console.error(layer)
                if (fiberConnections.includes(fiberId)) {
                  this.showMessage(`当前端口已有连线，请选择其他端口`)
                  return
                }
                const clickedPoint = e.latlng
                const clickedX = clickedPoint.lng
                // 获取中心线的X坐标（假设地图中心是分界线）
                const mapCenter = switchboxMapObj.getCenter().lng
                // 如果还没有选择点，直接添加第一个点
                if (drawingPoints.length === 0) {
                  drawingPoints.push({
                    latlng: clickedPoint,
                    layer: layer
                  })
                  if (notifyInstance) {
                    notifyInstance.message = '请选择另一端口'
                  }
                  return
                }
                const firstLayer = drawingPoints[0].layer;
                const currentLayer = layer;
                const firstLineId = get(firstLayer, 'feature.properties.SMID');
                const currentLineId = get(currentLayer, 'feature.properties.SMID');
                // 如果点击的是同一个
                if (firstLineId === currentLineId) {
                  return
                }
                // 添加第二个点
                drawingPoints.push({
                  latlng: clickedPoint,
                  layer: layer
                })
                // 如果已经选择了两个点
                if (drawingPoints.length === 2) {
                  // 移除临时连线
                  if (tempLine && switchboxMapObj.hasLayer(tempLine)) {
                    switchboxMapObj.removeLayer(tempLine)
                  }
                  this.createConnection()
                  // 不清除连线状态，只重置点数组
                  drawingPoints = []
                  // 重置临时线对象，为下一次连线做准备
                  tempLine = null
                  if (notifyInstance) {
                    notifyInstance.message = '连线完成，请继续选择要连接的端口'
                  }
                }
                return
              }
            })
          })
          if (isFirstLoad) {
            switchboxMapObj.fitBounds(bounds, { padding: [50, 50], zoom: 8 })
          }
        }
      } catch (err) {
        console.error('获取图层信息失败:', err)
      }
    },
    async createConnection() {
      if (drawingPoints.length !== 2) return
      const [point1, point2] = drawingPoints
      // 获取左侧点的颜色
      const leftPoint = point1.latlng.lng < point2.latlng.lng ? point1 : point2
      const rightPoint = point1.latlng.lng > point2.latlng.lng ? point1 : point2
      const userData = sessionStorage('userData')
      const lproperties = get(leftPoint, 'layer.feature.properties')
      const rproperties = get(rightPoint, 'layer.feature.properties')
      const params = {
        baseinfoid: 1,
        psmid: this.featureData.properties.SMID,
        userName: userData.userName,
        asmid: lproperties.SMID,
        bsmid: rproperties.SMID,
        rootid: lproperties.C_SYS_ROOT_ID,
        type: 1
      }

      try {
        const creatRes = await saveRcabTportApi(params)
        if (!creatRes.success) {
          this.$message.error(creatRes.message || '连线保存失败，请重新连线保存！')
          return
        }
        this.$message.success('连线创建成功')
        // 重置状态
        drawingPoints = []
        tempLine = null
        if (notifyInstance) {
          notifyInstance.message = '连线完成，请继续选择要连接的端口'
        }
        this.$nextTick(async() => {
          // 重新加载视图
          await this.layerOnMapByFeatures()
        })
      } catch (error) {
        console.error('保存连线失败:', error)
        this.$message.error('连线保存失败')
      }
    },
    getSwitchBoxTemplate(item) {
      this.nowCheckItem = item
      this.addCustomTouchEvents()
    },
    async addCustomTouchEvents() {
      try {
        // 清除上一次的图形
        this.clearTempRectGroup()
        this.tempRectGroup = L.featureGroup().addTo(switchboxMapObj)
        frameLayers = []
        var sqlParam = new SuperMap.GetFeaturesBySQLParameters({
          queryParameter: {
            name: 'C_RTEM_TEXT@capture',
            attributeFilter: `C_RPARA_EQUIPMENT_ID = ${this.nowCheckItem.id}`
          },
          datasetNames: ['capture:C_RTEM_TEXT', 'capture:C_RTEM_PORT', 'capture:C_RTEM_LINE', 'capture:C_RTEM_FRAME']
        })
        frameLayers = await new Promise(resolve => {
          featureService.getFeaturesBySQL(sqlParam, function(serviceResult) {
            resolve(serviceResult.result)
          })
        })
        var features = get(frameLayers, 'features.features', [])
        features.forEach(f => {
          var geometry = f.geometry
          var coords = geometry.coordinates
          console.error(f)
          if (geometry.type === 'LineString') {
            var points = coords.map(coord => [coord[1], coord[0]])
            L.polyline([points], { color: 'red' }).addTo(this.tempRectGroup)
          } else if (geometry.type === 'Point') {
            var myIcon = L.divIcon({ html: f.properties.texts[0], className: 'my-div-icon', iconSize: 10 })
            L.marker([coords[1], coords[0]], { icon: myIcon }).addTo(this.tempRectGroup)
          }
        })
        this.isMoving = true
        this.moveToFeature()
      } catch (e) {
        console.log('addCustomTouchEvents异常', e)
      }
    },
    clearTempRectGroup() {
      if (this.tempRectGroup) {
        switchboxMapObj.removeLayer(this.tempRectGroup)
        this.tempRectGroup = null
        switchboxMapObj.off('mousemove', this.moveHandler)
        switchboxMapObj.off('click', this.clickHandler)
      }
      if (messageInstance) {
        messageInstance.close()
      }
    },
    moveHandler(e) {
      try {
        var bounds = this.tempRectGroup.getBounds()
        var center = bounds.getCenter()
      } catch (err) {
        console.error('解析feature数据失败:', err)
      }
      const newCenter = e.latlng
      if (isNaN(newCenter.lat) || isNaN(newCenter.lng)) return
      const offset = {
        lat: newCenter.lat - center.lat,
        lng: newCenter.lng - center.lng
      }
      if (isNaN(offset.lat) || isNaN(offset.lng)) return
      const otherLayers = this.layerManager.dataFeatureGroup.getLayers()
      const originalCoords = {}
      this.tempRectGroup.eachLayer(layer => {
        if (layer instanceof L.Polyline || layer instanceof L.Polygon) {
          originalCoords[layer._leaflet_id] = layer.getLatLngs()
        }
      })
      this.tempRectGroup.eachLayer(layer => {
        if (layer instanceof L.Polyline || layer instanceof L.Polygon) {
          const latLngs = originalCoords[layer._leaflet_id]
          if (Array.isArray(latLngs)) {
            const newLatLngs = latLngs.map(points => {
              if (!Array.isArray(points)) {
                return L.latLng(points.lat + offset.lat, points.lng + offset.lng)
              }
              return points.map(point => {
                if (!point || isNaN(point.lat) || isNaN(point.lng)) return point
                return L.latLng(point.lat + offset.lat, point.lng + offset.lng)
              })
            })
            layer.setLatLngs(newLatLngs)
          }
        } else if (layer instanceof L.Marker) {
          const latLng = layer.getLatLng()
          if (!latLng || isNaN(latLng.lat) || isNaN(latLng.lng)) return
          layer.setLatLng([latLng.lat + offset.lat, latLng.lng + offset.lng])
        }
      })
      const newBounds = this.tempRectGroup.getBounds()
      const snapOffset = {lat: 0, lng: 0}
      otherLayers.forEach(layer => {
        if (layer instanceof L.Polyline || layer instanceof L.Polygon) {
          const layerBounds = layer.getBounds()
          // 精确计算边界差值，使用更小的阈值1
          const rightDiff = Math.abs(newBounds.getEast() - layerBounds.getEast())
          if (rightDiff <= 1) {
            snapOffset.lng = layerBounds.getEast() - newBounds.getEast()
            console.log('精确右侧吸附', {offset: snapOffset.lng})
          }
          // 其他方向同样使用更小阈值
          if (Math.abs(newBounds.getWest() - layerBounds.getWest()) <= 1) {
            snapOffset.lng = layerBounds.getWest() - newBounds.getWest()
          }
          if (Math.abs(newBounds.getNorth() - layerBounds.getNorth()) <= 1) {
            snapOffset.lat = layerBounds.getNorth() - newBounds.getNorth()
          }
          if (Math.abs(newBounds.getSouth() - layerBounds.getSouth()) <= 1) {
            snapOffset.lat = layerBounds.getSouth() - newBounds.getSouth()
          }
        }
      })
      if (snapOffset.lat !== 0 || snapOffset.lng !== 0) {
        this.tempRectGroup.eachLayer(layer => {
          if (layer instanceof L.Polyline || layer instanceof L.Polygon) {
            const latLngs = layer.getLatLngs()
            if (Array.isArray(latLngs)) {
              const newLatLngs = latLngs.map(points => {
                if (!Array.isArray(points)) {
                  return L.latLng(points.lat + snapOffset.lat, points.lng + snapOffset.lng)
                }
                return points.map(point => {
                  if (!point || isNaN(point.lat) || isNaN(point.lng)) return point
                  return L.latLng(point.lat + snapOffset.lat, point.lng + snapOffset.lng)
                })
              })
              layer.setLatLngs(newLatLngs)
            }
          } else if (layer instanceof L.Marker) {
            const latLng = layer.getLatLng()
            if (!latLng || isNaN(latLng.lat) || isNaN(latLng.lng)) return
            layer.setLatLng([latLng.lat + snapOffset.lat, latLng.lng + snapOffset.lng])
          }
        })
      }
      center = this.tempRectGroup.getBounds().getCenter()
    },
    clickHandler(e) {
      console.error(e)
      let f = get(frameLayers, 'features.features[0]', null)
      const nowFrameLayer = find(this.layerManager.dataFeatureGroup.getLayers(), layer => {
        const LAYERNAME = get(layer, 'feature.properties.LAYERNAME', '')
        return LAYERNAME === 'C_RCAB_FRAME'
      })
      const layerBounds = nowFrameLayer.getBounds()
      const rectBounds = this.tempRectGroup.getBounds()
      console.error(f)
      console.error(nowFrameLayer)
      const isIntersects = layerBounds.intersects(rectBounds) // 检查边界交叉且是有效feature图层
      console.error(rectBounds)
      if (isIntersects) {
        const params = {
          switchboxid: this.featureData.properties.SMID,
          switchboxrootid: this.featureData.properties.C_SYS_ROOT_ID,
          equiprootid: f.properties.C_SYS_ROOT_ID,
          c_rpara_equipment_id: f.properties.C_RPARA_EQUIPMENT_ID,
          coordinate: [rectBounds._southWest.lng, rectBounds._southWest.lat],
          userName: get(sessionStorage('userData'), 'userName', ''),
          c_eng_baseinfo_id: 1
        }
        console.error(params)
        this.isMoving = false
        insertSwitchBoxEquipmentApi(params).then(res => {
          if (!res.success) {
            this.$message.error(res.message || '放置设备失败，请重试', 'error')
            return
          }
          this.clearTempRectGroup()
          this.$nextTick(() => {
            this.layerOnMapByFeatures()
          })
        })
      } else {
        this.$message.error('需要在有效图层范围内放置')
      }
    },
    contextHandler(e) {
      e.originalEvent.preventDefault()
      this.clearTempRectGroup()
    },
    moveToFeature() {
      let f = get(frameLayers, 'features.features[0]', null)
      if (!f) {
        this.$message.error('当前无有效数据，请重新选择')
        return
      }
      this.showMessage('在蓝色区域内放置,右键取消', 'warning', true)
      // 在moveToFeature方法中添加右键事件绑定
      switchboxMapObj.on('contextmenu', this.contextHandler)
      switchboxMapObj.on('mousemove', this.moveHandler)
      switchboxMapObj.on('click', this.clickHandler)
    },
    async handleToolbarCommand(command) {
      if (this.isDrawing) {
        this.isDrawing = false; // 停止绘制
        switchboxMapObj.pm.disableDraw(); // 禁用绘制
      }
      const layers = this.layerManager.dataFeatureGroup.getLayers()
      if (layers.length < 2 && command !== 'jigui') {
        return this.$message.error('放置机架后再执行其他操作')
      }
      this.clearTempRectGroup()
      switch (command) {
        case 'jigui':
          this.panelTitle = '机架列表'
          this.panelData = this.boxsData
          this.showFloatingPanel = true
          break
        case 'guangfenzhiqi':
          this.panelTitle = '光分支器模块'
          this.panelData = this.linesData
          this.showFloatingPanel = true
          break
        case 'switchbox_fiberlink':
          if (this.treeDialogVisible) return
          console.error(nowFeatureData)
          if (!nowFeatureData || nowFeatureData.properties.FEATURENAME !== '端口') {
            this.$message.error('请先选择端口')
            return
          }
          const circle = L.circle([this.featureData.geometry.coordinates[1], this.featureData.geometry.coordinates[0]], {
            radius: 30, // 单位为米
            opacity: 0,
            fillOpacity: 0
          }).addTo(mapObj)
          // 根据圆形的范围计算边界
          const getParams = attributeFilter => {
            const p = {
              datasetNames: ['capture:C_PRO_OPTLINE'],
              spatialQueryMode: 'INTERSECT',
              fromIndex: 0,
              toIndex: 1000
            }
            if (attributeFilter) {
              p.queryParameter = { attributeFilter }
            } else {
              p.bounds = circle.getBounds()
            }
            var boundsParam = attributeFilter ? new SuperMap.GetFeaturesBySQLParameters(p) : new SuperMap.GetFeaturesByBoundsParameters(p)
            return boundsParam
          }
          let allLine = await new Promise(resolve => {
            featureService.getFeaturesByBounds(getParams(false), serviceResult => {
              resolve(serviceResult.result)
            })
          })
          allLine = get(allLine, 'features.features', [])
          circle.remove()
          console.error(allLine)
          const data = {
            smid: allLine.map(item => item.properties.SMID).join(','),
            userName: sessionStorage('userData').userName,
            c_eng_baseinfo_id: 1,
            psmid: this.featureData.properties.SMID,
            prootid: this.featureData.properties.C_SYS_ROOT_ID
          }
          const lineTreeData = await getCableTreeByOptlineidsApi(data)
          console.error(lineTreeData)
          this.initTreeData(lineTreeData)
          this.treeDialogVisible = true
          break
        case 'choseitem':
          // 端口连接
          if (this.isDrawingLine) {
            this.stopDrawing()
          } else {
            this.startDrawing()
          }
          break
        case 'setline':
          // 画线
          console.error(switchboxMapObj.pm)
          switchboxMapObj.pm.enableDraw('Line', {
            snappable: true,
            snapDistance: 20
          })
          break
        case 'setrectangle':
          // 画方形
          console.error(switchboxMapObj.pm)
          switchboxMapObj.pm.enableDraw('Polygon', {
            snappable: true,
            snapDistance: 20
          })
          break
        default:
          break
      }
    },
    // 开始连线
    startDrawing() {
      this.isDrawingLine = true
      drawingPoints = []
      // 创建或更新通知
      if (!notifyInstance) {
        notifyInstance = this.$notify({
          title: '开始连线',
          message: '请点击要连接的端口',
          duration: 0,
          showClose: true,
          type: 'info',
          onClose: () => {
            // 关闭通知时停止连线
            this.stopDrawing()
          }
        })
      } else {
        notifyInstance.message = '请点击要连接的端口'
      }
      // 添加地图点击事件监听
      if (switchboxMapObj) {
        // 添加鼠标移动事件监听
        switchboxMapObj.on('mousemove', this.handleMouseMove)
      }
    },
    // 停止连线
    stopDrawing() {
      this.isDrawingLine = false
      drawingPoints = []
      // 移除临时连线
      if (tempLine && switchboxMapObj.hasLayer(tempLine)) {
        switchboxMapObj.removeLayer(tempLine)
      }
      tempLine = null
      // 移除地图点击事件监听
      if (switchboxMapObj) {
        switchboxMapObj.off('mousemove', this.handleMouseMove)
      }
      // 关闭通知，但不触发onClose回调以避免循环
      if (notifyInstance) {
        // 移除onClose回调以避免循环调用
        notifyInstance.onClose = null
        notifyInstance.close()
        notifyInstance = null
      }
    },
    // 处理鼠标移动事件
    handleMouseMove(e) {
      // 如果已经选择了第一个点，则更新临时连线
      if (drawingPoints.length === 1) {
        const firstPoint = drawingPoints[0].latlng
        const currentPoint = e.latlng
        // 如果临时线不存在，创建新的临时线
        if (!tempLine) {
          tempLine = L.polyline([firstPoint, currentPoint], {
            color: 'red',
            weight: 2,
            dashArray: '5, 5',  // 使用虚线样式
            opacity: 0.7,
            interactive: false
          }).addTo(switchboxMapObj)
        } else {
          // 如果临时线已存在，只更新其位置
          tempLine.setLatLngs([firstPoint, currentPoint])
        }
      }
    },
    // 批量连接
    batchConnect(node) {
      const selectedNodes = this.getCheckedNodes()
      console.log('批量连接节点:', selectedNodes)
      // 这里添加批量连接的业务逻辑
      if (!selectedNodes.length) {
        this.$message.error('请选择要连接的节点')
        return
      }
    },
    // 批量删除
    batchDelete(node) {
      const selectedNodes = this.getCheckedNodes()
      console.log('批量删除节点:', selectedNodes)
      // 这里添加批量删除的业务逻辑
      if (!selectedNodes.length) {
        this.$message.error('请选择要删除连接的节点')
        return
      }
    },
    // 单个连接
    connect(node) {
      console.log('连接节点:', node)
      // 这里添加单个连接的业务逻辑
      const params = {
        tportid: nowFeatureData.properties.C_SYS_ROOT_ID,
        rootid: nowFeatureData.properties.SMID,
        linesmid: node.data.linesmid,
        linerootid: node.data.linerootid,
        linestructid: node.data.linestructid,
        psmid: this.featureData.properties.SMID,
        prootid: this.featureData.properties.C_SYS_ROOT_ID,
        userName: sessionStorage('userData').userName,
        baseinfoid: 1
      }
      saveSwitchbox_PortLineApi(params).then(res => {
        if (!res.success) {
          this.$message.error(res.message || '连接失败，请重试')
          return
        }
      })
    },
    // 删除单个连接
    deleteConnect(node) {
      console.log('删除连接节点:', node)
      // 这里添加删除单个连接的逻辑
    },
    handleCustomCheckChange(node, data) {
      // 处理子节点选中状态
      const setChildrenChecked = (node, checked) => {
        if (node.childNodes) {
          node.childNodes.forEach(child => {
            child.data.checked = checked
            if (child.childNodes) setChildrenChecked(child, checked)
          })
        }
      }
      // 处理父节点选中状态
      const checkParent = node => {
        if (node.parent) {
          const allChildrenChecked = node.parent.childNodes.every(child => child.data.checked)
          node.parent.data.checked = allChildrenChecked
          checkParent(node.parent)
        }
      }
      setChildrenChecked(node, data.checked)
      checkParent(node)
    },
    // 确保processNodeData正确处理selectParent
    processNodeData(nodes) {
      return nodes.map(node => {
        const processed = {
          ...node,
          selectParent: String(node.selectParent).toLowerCase() === 'true',
          open: String(node.open).toLowerCase() === 'true'
        }
        if (node.children) {
          processed.children = this.processNodeData(node.children)
        }
        return processed
      })
    },
    hasSelectedChildren(node) {
      return node.children && node.children.some(child => child.checked || this.hasSelectedChildren(child))
    },
    // 修改initTreeData方法
    initTreeData(data) {
      const addCheckedProperty = (nodes) => {
        return nodes.map(node => {
          const newNode = {
            ...node,
            checked: false // 默认不选中
          }
          if (newNode.iconsrc) {
            const noWelded = newNode.iconsrc.indexOf('NoWeld') !== -1
            const weldOne = newNode.iconsrc.indexOf('WeldOne') !== -1
            const weldTwo = newNode.iconsrc.indexOf('WeldTwo') !== -1
            if (noWelded) {
              newNode.iconsrc = imgNoWeld
            }
            if (weldOne) {
              newNode.iconsrc = imgWeldOne
            }
            if (weldTwo) {
              newNode.iconsrc = imgWeldTwo
            }
            newNode.weldTwo = weldTwo
          }
          console.error(newNode)
          if (node.children && node.children.length > 0) {
            newNode.children = addCheckedProperty(node.children)
          } else {
            delete newNode.children
          }
          return newNode
        })
      }
      this.treeData = addCheckedProperty(data)
      this.expandedKeys = this.getExpandedKeys(data)
    },
    getExpandedKeys(data) {
      const keys = []
      const walk = nodes => {
        nodes.forEach(node => {
          if (node.open === 'true') keys.push(node.id)
          if (node.children) walk(node.children)
        })
      }
      walk(data)
      return keys
    },
    handleNodeMouseEnter(node) {
      this.hoverNodeId = node.id
      this.currentNodeId = node.id // 替换this.$refs.tree.setCurrentKey(node.id)
    },
    handleNodeMouseLeave() {
      this.hoverNodeId = null
    },
    getCheckedNodes() {
      const result = []
      const walk = (nodes) => {
        nodes.forEach(node => {
          if (node.checked) result.push(node)
          if (node.children) walk(node.children)
        })
      }
      walk(this.processedTreeData)
      return result
    },
    // 显示消息提示
    showMessage(message, type = 'warning', persistent = false) {
      if (messageInstance) {
        messageInstance.close()
      }
      messageInstance = this.$message({
        message,
        type,
        duration: persistent ? 0 : 3000,
        onClose: () => {
          messageInstance = null
        }
      })
    },
    closePanel() {
      this.clearTempRectGroup()
      this.showFloatingPanel = false
    }
  },
  beforeDestroy() {
    switchboxMapObj.off('zoomend', this.afterMoveend)
    if (switchboxMapObj) switchboxMapObj.remove()
    if (messageInstance) {
      messageInstance.close()
      messageInstance = null
    }
    if (notifyInstance) {
      notifyInstance.close()
      notifyInstance = null
    }
    switchboxMapObj = null
    window.removeEventListener('beforeunload', this.handleBeforeUnload)
  }
}
</script>

<style lang="scss">
@import url(./index.scss);
// 增加图形元素的CSS样式
.leaflet-marker-icon,
.leaflet-marker-shadow {
  transform: scale(1.5); /* 放大1.5倍 */
}
</style>
